import serial
from threading import Thread,Lock
import time
from gpiozero import LED

user_serial_name  = "/dev/ttyAMA0"
dev_serial_name   = "/dev/ttyUSB0"
dev_rx_data_list = []
user_rx_data_list = []
dev_rx_lock = Lock()
user_rx_lock = Lock()
dev_ser = serial.Serial(timeout=0.0)
user_ser = serial.Serial(timeout=0.0)

have_dev_data = False
dev_old_ticks = int(time.time())

resString = '';

def open_dev_serial():
   global dev_ser
   error = True
   while error:
      try:
         dev_ser.port = dev_serial_name
         dev_ser.baudrate = 115200
         dev_ser.open()
         if dev_ser.isOpen():
            error = False            
            return
      except serial.SerialException:
         error = True
         dev_ser.close()
         time.sleep(2)
         
def open_user_serial():
   global user_ser
   error = True
   while error:
      try:
         user_ser.port = user_serial_name
         user_ser.baudrate = 115200
         user_ser.open()
         if user_ser.isOpen():
            error = False
            return
      except serial.SerialException:
        error = True
        user_ser.close()
        time.sleep(2)
   

def dev_serial_run():

   global dev_old_ticks
   global have_dev_data
   global dev_ser
   global resString
   
   rx_count = 0
   error = False
   open_dev_serial()
   if dev_ser.isOpen():
      error = False
      print("Open the Dev serial")
   
   while True:
      time.sleep(0.005)  #5ms

      if error:
         open_dev_serial()
         if dev_ser.isOpen():
            error = False
            print("Reopen the Dev serial")
         else:
            continue
      
      try: 
         ### 发送数据
         user_rx_lock.acquire()
         copy_list = user_rx_data_list.copy()
         user_rx_data_list.clear()
         user_rx_lock.release()
         res = ''

         for r in copy_list:
            res += r
         if len(res)>0:
            print("Dev Send: "+res)
            dev_ser.write(bytes(res, 'Latin-1'))
      
         ### 读取数据

         data = dev_ser.read(512)
         rr = str(data, encoding = "Latin-1")
                  
         if len(rr)>0:
            for cc in rr:
               if (cc=='\r') or (cc=='\n'):
                  resString = '';
               elif cc=='%':
                  ss = resString.split()
                  if len(ss)!=5:
                     resString = ''
                     continue;
                  yes = True
                  for gg in ss[0]:
                     if gg not in '0123456789.':
                        yes = False
                  if yes==False:
                     resString = ''
                     continue
                  
                  print(ss)
                  print(">>>"+ss[0]+"\r\n")
                  rx_count += 1
                  have_dev_data = True
                  dev_old_ticks = int(time.time())
                  if (rx_count%200)==0:
                     print("Dev have data\n")
                  dev_rx_lock.acquire()
                  dev_rx_data_list.append(ss[0]+"\r\n") #将接受到的数据转换成字符串  
                  dev_rx_lock.release()
                  resString = ''
               else:
                  resString += cc
           
         if int(time.time())-dev_old_ticks>=5:
            have_dev_data = False
      except serial.SerialException as e:
        have_dev_data = False
        error = True
        dev_ser.close()
        time.sleep(1)
        print(e)
        print("Dev Serial Error!")
   
def user_serial_run():

   rx_count = 0
   error = False
   open_user_serial()
   
   if user_ser.isOpen():
      error = False
      print("Open the User serial")
   
   while True:
      time.sleep(0.005)  #5ms
      
      if error:
         open_user_serial()
         if user_ser.isOpen():
            error = False
            print("Reopen the User serial")
         else:
            continue
      
      try:
         ### 发送数据
         if user_ser.writable():
            dev_rx_lock.acquire()
            copy_list = dev_rx_data_list.copy()
            dev_rx_data_list.clear()
            dev_rx_lock.release()
            res = ''
         
            for r in copy_list:
              res += r
            if len(res)>0:
               user_ser.write(bytes(res, encoding='Latin-1'))
      
      ### 读取数据
         data = user_ser.read(512)
         rr = str(data, encoding = "Latin-1")
         if len(rr)>0:
            print("User Read: "+rr)
            rx_count += 1
            user_rx_lock.acquire()
            user_rx_data_list.append(rr)  
            user_rx_lock.release()
      except serial.SerialException:
         error = True
         user_ser.close()
         time.sleep(1)
         
def led_run():
   led = LED("GPIO17")
   led.off()
   count = 0
   
   global have_dev_data
   
   while True:
      count = count + 1
      time.sleep(0.01)  #10ms
      
      if have_dev_data:
         if count<=10:
            led.on()
         elif count<=20:
            led.off()
         else:
            count = 0
      else:
         if count<=100:
            led.on()
         elif count<=200:
            led.off()
         else:
            count = 0

### 创建线程      
dev_thread = Thread(target=dev_serial_run)
user_thread = Thread(target=user_serial_run)
led_thread = Thread(target=led_run)

dev_thread.start()
user_thread.start()
led_thread.start()
print("Serial Threads Running!...\n")

